/**
 * Copyright (c) 2015-2016, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.wzapp.sitposture.common.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

@Slf4j
public class DateUtil {

    private static final Long MIN_TIME = 1000000000000L;

    /**
     * 获取YYYY格式
     *
     * @return
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 获取YYYY格式
     *
     * @return
     */
    public static String getYear(Date date) {
        return formatDate(date, "yyyy");
    }

    /**
     * 获取YYYY-MM-DD格式
     *
     * @return
     */
    public static String getDay() {
        return formatDate(new Date(), "yyyy-MM-dd");
    }

    /**
     * 获取YYYY-MM-DD格式
     *
     * @return
     */
    public static String getDay(Date date) {
        return formatDate(date, "yyyy-MM-dd");
    }

    /**
     * 获取YYYYMMDD格式
     *
     * @return
     */
    public static String getDays() {
        return formatDate(new Date(), "yyyyMMdd");
    }

    /**
     * 获取YYYYMMDD格式
     *
     * @return
     */
    public static String getDays(Date date) {
        return formatDate(date, "yyyyMMdd");
    }

    /**
     * 获取YYYY-MM-DD HH:mm:ss格式
     *
     * @return
     */
    public static String getTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 获取YYYY-MM-DD HH:mm:ss.SSS格式
     *
     * @return
     */
    public static String getMsTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");
    }

    /**
     * 获取YYYYMMDDHHmmss格式
     *
     * @return
     */
    public static String getAllTime() {
        return formatDate(new Date(), "yyyyMMddHHmmss");
    }

    /**
     * 获取YYYY-MM-DD HH:mm:ss格式
     *
     * @return
     */
    public static String getTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 2  * 将String字符串转换为java.sql.Timestamp格式日期,用于数据库保存
     * 3  * @param strDate
     * 4  *            表示日期的字符串
     * 5  * @param dateFormat
     * 6  *            传入字符串的日期表示格式（如："yyyy-MM-dd HH:mm:ss"）
     * 7  * @return java.sql.Timestamp类型日期对象（如果转换失败则返回null）
     * 8
     */
    public static java.sql.Timestamp strToSqlDate(String strDate, String dateFormat) {
        SimpleDateFormat sf = new SimpleDateFormat(dateFormat);
        java.util.Date date = null;
        try {
            date = sf.parse(strDate);
            if (null==date){
                return null;
            }
            java.sql.Timestamp dateSQL = new java.sql.Timestamp(date.getTime());
            return dateSQL;
        } catch (ParseException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    /**
     * 将java.sql.Timestamp对象转化为String字符串
     *
     * @param time      要格式的java.sql.Timestamp对象
     * @param strFormat 输出的String字符串格式的限定（如："yyyy-MM-dd HH:mm:ss"）
     * @return 表示日期的字符串
     */
    public static String dateToStr(java.sql.Timestamp time, String strFormat) {
        DateFormat df = new SimpleDateFormat(strFormat);
        String str = df.format(time);
        return str;
    }

    /**
     * 将java.util.Date对象转化为String字符串
     *
     * @param date      要格式的java.util.Date对象
     * @param strFormat 输出的String字符串格式的限定（如："yyyy-MM-dd HH:mm:ss"）
     * @return 表示日期的字符串
     */
    public static String dateToStr(java.util.Date date, String strFormat) {
        SimpleDateFormat sf = new SimpleDateFormat(strFormat);
        String str = sf.format(date);
        return str;
    }

    /**
     * 将java.util.Date对象转化为java.sql.Timestamp对象
     *
     * @param date 要转化的java.util.Date对象
     * @return 转化后的java.sql.Timestamp对象
     */
    public static java.sql.Timestamp dateToTime(java.util.Date date) {
        String strDate = dateToStr(date, "yyyy-MM-dd HH:mm:ss SSS");
        return strToSqlDate(strDate, "yyyy-MM-dd HH:mm:ss SSS");
    }

    public static String formatDate(Date date, String pattern) {
        String formatDate = null;
        if (StringUtils.isNotBlank(pattern)) {
            formatDate = DateFormatUtils.format(date, pattern);
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }
        return formatDate;
    }

    /**
     * @param s
     * @param e
     * @return boolean
     * @throws
     * @Title: compareDate
     * @Description:(日期比较，如果s>=e 返回true 否则返回false)
     * @author ql
     */
    public static boolean compareDate(String s, String e) {
        if (parseDate(s) == null || parseDate(e) == null) {
            return false;
        }
        return parseDate(s).getTime() >= parseDate(e).getTime();
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static Date parseDate(String date) {
        return parse(date, "yyyy-MM-dd");
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static Date parseTime(String date) {
        return parse(date, "yyyy-MM-dd HH:mm:ss");
    }
    /**
     * 格式化日期
     *
     * @return
     */
    public static Long parseTimeToLong(String date) {
        if (date.contains(".")){
            date = date.substring(0,date.indexOf("."));
        }
        Date parse = parse(date, "yyyy-MM-dd HH:mm:ss");
        if (null!=parse){
            return parse.getTime();
        }else {
            log.error("DateUtil.parseTimeToLong，日期格式化异常=========");
        }
        return null;
    }
    /**
     * 格式化日期
     *
     * @return
     */
    public static Timestamp parseTimeToTimeStamp(String date) {

        Date parse = parse(date, "yyyy-MM-dd HH:mm:ss");
        if (null!=parse){
            return new Timestamp(parse.getTime());
        }else {
            log.error("DateUtil.parseTimeToTimeStamp，日期格式化异常=========");
        }
        return null;
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static Date parse(String date, String pattern) {
        try {
            return DateUtils.parseDate(date, pattern);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static String format(Date date, String pattern) {
        return DateFormatUtils.format(date, pattern);
    }

    /**
     * 格式化时间长度
     *
     * @return
     */
    public static String formatDuration(Integer seconds) {
        StringBuffer sb = new StringBuffer();
        int hour = seconds / (60 * 60);
        int min_second = seconds % (60 * 60);
        if (hour > 0) {
            sb.append(hour).append("小时");
        }
        int min = min_second / 60;
        int second = min_second % 60;

        if (min > 0 && second > 0) {
            sb.append(min).append("分钟");
        } else if (min > 0 && second == 0) {
            sb.append(min).append("分");
        }
        if (second > 0) {
            sb.append(second).append("秒");
        }

        return sb.toString();
    }

    /**
     * 把日期转换为Timestamp
     *
     * @param date
     * @return
     */
    public static Timestamp format(Date date) {
        return new Timestamp(date.getTime());
    }

    /**
     * 校验日期是否合法
     *
     * @return
     */
    public static boolean isValidDate(String s) {
        return parse(s, "yyyy-MM-dd HH:mm:ss") != null;
    }

    /**
     * 校验日期是否合法
     *
     * @return
     */
    public static boolean isValidDate(String s, String pattern) {
        return parse(s, pattern) != null;
    }

    public static int getDiffYear(String startTime, String endTime) {
        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        try {
            int years = (int) (((fmt.parse(endTime).getTime() - fmt.parse(
                    startTime).getTime()) / (1000 * 60 * 60 * 24)) / 365);
            return years;
        } catch (Exception e) {
            // 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
            return 0;
        }
    }

    /**
     * <li>功能描述：时间相减得到天数
     *
     * @param beginDateStr
     * @param endDateStr
     * @return long
     * @author ql
     */
    public static long getDaySub(String beginDateStr, String endDateStr) {
        long day = 0;
        SimpleDateFormat format = new SimpleDateFormat(
                "yyyy-MM-dd");
        try {
            Date beginDate = format.parse(beginDateStr);
            Date endDate = format.parse(endDateStr);
            day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
            // System.out.println("相隔的天数="+day);
            return Math.abs(day);
        } catch (ParseException e) {
            log.error("DateUtil.getDaySub=日期格式化异常");
        }
        return day;
    }

    /**
     * 得到n天之后的日期
     *
     * @param days
     * @return
     */
    public static String getAfterDayDate(String days) {
        int daysInt = Integer.parseInt(days);

        Calendar canlendar = Calendar.getInstance(); // java.util包
        canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
        Date date = canlendar.getTime();

        SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdfd.format(date);

        return dateStr;
    }

    /**
     * 得到n天之后的日期
     *
     * @param days
     * @return
     */
    public static Long getAfterDayDate(Long time, int days) {
        // java.util包
        Calendar canlendar = Calendar.getInstance();
        if (time.compareTo(MIN_TIME) < 0) {
            time = 1000 * time;
        }
        canlendar.setTime(new Date(time));
        // 日期减 如果不够减会将月变动
        canlendar.add(Calendar.DATE, days);

        return canlendar.getTime().getTime();
    }

    /**
     * 得到n小时之前的日期
     *
     * @param time
     * @param hours
     * @return
     */
    public static Long getAfterHoursDate(Long time, int hours) {

        Calendar canlendar = Calendar.getInstance();
        if (time.compareTo(MIN_TIME) < 0) {
            time = 1000 * time;
        }
        canlendar.setTime(new Date(time));
        canlendar.add(Calendar.HOUR_OF_DAY, hours);

        return canlendar.getTime().getTime();
    }

    /**
     * 得到n天之后是周几
     *
     * @param days
     * @return
     */
    public static String getAfterDayWeek(String days) {
        int daysInt = Integer.parseInt(days);

        Calendar canlendar = Calendar.getInstance(); // java.util包
        canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
        Date date = canlendar.getTime();

        SimpleDateFormat sdf = new SimpleDateFormat("E");
        String dateStr = sdf.format(date);

        return dateStr;
    }
    /**
     * 获取当前时间的上一个月
     *
     * @return
     */
    public static Long getLastMonthByNow() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, -1);
        return cal.getTimeInMillis();
    }

    /**
     * 获取当天的开始时间，精确到毫秒
     *
     */
    public static Long getStartTime() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTimeInMillis();
    }

    /**
     * 获取当天的结束时间，精确到毫秒
     *
     */
    public static Long getEndTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTimeInMillis();
    }

    /**
     * 获取当前时间之前或之后几分钟 minute
     */
    public static Timestamp getTimeByMinute(int minute) {

        Calendar calendar = Calendar.getInstance();

        calendar.add(Calendar.MINUTE, minute);

        return DateUtil.dateToTime(calendar.getTime());
    }

    public static void main(String[] args) {
//		System.out.println(getTime(new Date()));
//		System.out.println(getAfterDayWeek("3"));
//        System.out.println(36506 / (60 * 60));
//        System.out.println(36506 % (60 * 60));
//        System.out.println(506 / (60));
//        System.out.println(506 % (60));
//
//        System.out.println(formatDuration(3650));
//        Long time = getAfterHoursDate(1533105043L,-1);
//        System.out.println(format(new Date(time)));
//        System.out.println(DateUtil.getLastMonthByNow());
//        System.out.println(DateUtil.getStartTime());
//        System.out.println(DateUtil.getEndTime());

//        System.out.println(format(new Date(),"yyyyMMddHHmmss"));

//        System.out.println(parseTimeToLong("2018-08-30 11:43:39.654"));
//        System.out.println(parseTimeToLong("2018-08-30 11:43:39.654"));
//        System.out.println(parseTimeToLong("1535644800000"));
        System.out.println(getAllTime());
    }

}
